package de.tabuma.soap.logik;

import java.util.logging.*;
import java.util.*;

import de.tabuma.soap.entity.*;
import de.tabuma.soap.entity.wsdl.*;
import de.tabuma.soap.entity.xsd.*;

/**
  * @author $Author: alefen $
  * @version $Revision: 1.1 $
  * @since $Date: 2009/12/30 02:53:55 $
 */
public class SchemaFacade {

    private static final Logger log = Logger.getLogger(SchemaFacade.class.getName());
    private static Hashtable speicher = new Hashtable();
    /**
     * Changes an relative import or include url into an absolute
     * @param wsdl
     * @param url
     */
    public static void substituteUrl(TDefinitions wsdl,String url) {
        List<XsSchema> schemaList = getSchema(wsdl);
        substituteUrl(schemaList, url);
    }

    /**
     * TODO
     * @param schemaList
     * @param url
     */
    public static void substituteUrl(List<XsSchema> schemaList,String url) {
        List<Long> anyElementList = getSubElementOfSchema(schemaList);
        log.fine("schemaList:"+schemaList);
        log.fine("anyElementList:"+anyElementList);
        log.fine("url:"+url);
        for(int i=0;i<anyElementList.size();i++) {
            AnyElement anyElement = PMF.get(anyElementList.get(i),new AnyElement());
            Object object = anyElement.toObject();
            log.fine("object:"+object);
            if(XsImport.class.isInstance(object)) {
                XsImport xsImport = (XsImport) object;
                if(xsImport.getSchemaLocation().indexOf("http://")==-1) {
                    if(xsImport.getSchemaLocation().indexOf("https://")==-1) {
                        int slashIndex = url.lastIndexOf("/");
                        if(slashIndex!=-1) {
                            String substring = url.substring(0,slashIndex+1)+xsImport.getSchemaLocation();
                            xsImport.setSchemaLocation(substring);
                            PMF.doUpdate(xsImport);
                        }
                    }
                }
            }
            if(XsInclude.class.isInstance(object)) {
                XsInclude xsInclude = (XsInclude) object;
                if(xsInclude.getSchemaLocation().indexOf("http://")==-1) {
                    if(xsInclude.getSchemaLocation().indexOf("https://")==-1) {
                        int slashIndex = url.lastIndexOf('/');
                        if(slashIndex!=-1) {
                            String substring = url.substring(0,slashIndex+1)+xsInclude.getSchemaLocation();
                            xsInclude.setSchemaLocation(substring);
                            PMF.doUpdate(xsInclude);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param wsdl
     * @return
     */
    public static List<XsSchema> getSchema(TDefinitions wsdl) {
        if(speicher.get(wsdl)!=null) {
            return (List<XsSchema>) speicher.get(wsdl);
        }
        ArrayList<XsSchema> arrayList = new ArrayList<XsSchema>();
        List<TTypes> list = SoapFacade.getTypes(wsdl);
        log.fine("Typelist:"+list.size());
        for(int i=0;i<list.size();i++) {
            TTypes typ = list.get(i);
            for(int j=0;j<typ.getSchema().size();j++) {
                XsSchema xsSchema = (XsSchema) PMF.get(typ.getSchema().get(j), new XsSchema());
                arrayList.add(xsSchema);
            }
        }
        speicher.put(wsdl, arrayList);
        return arrayList;
    }

    /**
     *
     * @param xsSchema
     * @return
     */
    public static List<Long> getSubElementOfSchema(List<XsSchema> xsSchema) {
        ArrayList<Long> arrayList = new ArrayList<Long>();
        log.fine("xsSchema:"+xsSchema);
        for(int i=0;i<xsSchema.size();i++) {
            XsSchema mySchema = xsSchema.get(i);
            if(mySchema.getXsIncludeOrXsImportOrXsRedefineOrXsAnnotationOrXsSimpleTypeOrXsComplexTypeOrXsElementOrXsAttributeOrXsAttributeGroupOrXsGroupOrXsNotation()!=null) {
                List<Long> myList = mySchema.getXsIncludeOrXsImportOrXsRedefineOrXsAnnotationOrXsSimpleTypeOrXsComplexTypeOrXsElementOrXsAttributeOrXsAttributeGroupOrXsGroupOrXsNotation();
                arrayList.addAll(myList);
            }
        }
        return arrayList;
    }
}
